package com.example.composableexample.checkbox

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material3.Checkbox
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.material3.TriStateCheckbox
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshots.SnapshotStateList
import androidx.compose.runtime.toMutableStateList
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.state.ToggleableState
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewmodel.compose.viewModel
import kotlinx.coroutines.delay

@Composable
fun TriStateCheckboxSimple() {
    Column {
        val (state, onStateChange) = remember { mutableStateOf(true) }
        val (state2, onStateChange2) = remember { mutableStateOf(true) }

        val parentState = remember(state, state2) {
            if (state && state2) ToggleableState.On
            else if (!state && !state2) ToggleableState.Off
            else ToggleableState.Indeterminate
        }

        val onParentClick = {
            val s = parentState != ToggleableState.On
            onStateChange(s)
            onStateChange2(s)
        }

        TriStateCheckbox(state = parentState, onClick = onParentClick)
        Spacer(modifier = Modifier.size(25.dp))
        Column(modifier = Modifier.padding(10.dp, 0.dp, 0.dp, 0.dp)) {
            Checkbox(checked = state, onCheckedChange = onStateChange)
            Spacer(modifier = Modifier.size(25.dp))
            Checkbox(checked = state2, onCheckedChange = onStateChange2)
        }

    }
}

@OptIn(ExperimentalMaterial3Api::class)
@Preview
@Composable
fun SelectAll() {
    var selectAllChecked by rememberSaveable {
        mutableStateOf(false)
    }
    val viewModel = viewModel<CheckboxViewModel>()
    val checkboxState by viewModel.checkboxState
    Column(modifier = Modifier.fillMaxSize()) {
        Row(modifier = Modifier.fillMaxWidth(),
            verticalAlignment = Alignment.CenterVertically,
            horizontalArrangement = Arrangement.SpaceBetween) {
            Text(text = "全选", modifier = Modifier.padding(start = 16.dp))
            Checkbox(checked = selectAllChecked, onCheckedChange = {
                selectAllChecked = !selectAllChecked
                checkboxState.selectAll(it)
            })
        }
        LazyColumn {
            items(checkboxState.checkboxStateList) { state ->
                Row(modifier = Modifier.fillMaxWidth(),
                    verticalAlignment = Alignment.CenterVertically,
                    horizontalArrangement = Arrangement.SpaceBetween) {
                    Text(text = state.checkboxTest.name, modifier = Modifier.padding(start = 16.dp))
                    Row {
                        Checkbox(checked = state.checked, onCheckedChange = {
                            checkboxState.changeTestChecked(state.checkboxTest, it)
                            selectAllChecked = checkboxState.isSelectAll()
                        })
                        IconButton(onClick = { checkboxState.remove(state) }) {
                            Icon(imageVector = Icons.Default.Close, contentDescription = "remove")
                        }
                    }
                }
            }
        }

    }
}


class CheckboxViewModel : ViewModel() {

    private val checkboxItemState =
        getCheckboxTests().map { CheckboxItemState(checkboxTest = it) }.toMutableStateList()

    val checkboxState
        get() = mutableStateOf(CheckboxState(checkboxItemState))

//    fun changeTestChecked(checkboxTest: CheckboxTest, checked: Boolean) {
//        _checkboxState.find { it.checkboxTest.id == checkboxTest.id }?.let {
//            it.checked = checked
//        }
//    }
//
//    fun selectAll(selected: Boolean) {
//        _checkboxState.forEach { it.checked = selected }
//    }
//
//    fun isSelectAll() = _checkboxState.filter { it.checked }.size == getCheckboxTests().size

}

data class CheckboxTest(
    val id: Int,
    val name: String,
)

class CheckboxState(val checkboxStateList: SnapshotStateList<CheckboxItemState>) {

    fun changeTestChecked(
        checkboxTest: CheckboxTest,
        checked: Boolean,
    ) {
        checkboxStateList.find { it.checkboxTest.id == checkboxTest.id }?.let {
            it.checked = checked
        }
    }

    fun selectAll(selected: Boolean) {
        checkboxStateList.forEach { it.checked = selected }
    }

    fun isSelectAll() =
        checkboxStateList.filter { it.checked }.size == getCheckboxTests().size

    fun remove(checkboxItemState: CheckboxItemState) {
        checkboxStateList.remove(checkboxItemState)
    }
}

class CheckboxItemState(
    val checkboxTest: CheckboxTest,
    initialChecked: Boolean = false,
) {
    var checked by mutableStateOf(initialChecked)
}

private fun getCheckboxTests() = List(50) { i -> CheckboxTest(id = i, name = "CheckboxTest #$i") }